package org.jing.core.logger.log4j;

import org.apache.log4j.LogManager;
import org.apache.log4j.spi.LoggerRepository;
import org.jing.core.lang.JingException;
import org.jing.core.logger.JingLoggerConfiguration;
import org.jing.core.logger.itf.JingLoggerFactoryItf;
import org.jing.core.logger.itf.JingLoggerItf;
import org.jing.core.logger.itf.JingLoggerLevelItf;
import org.jing.core.logger.sys.SingleLogger;
import org.jing.core.util.StringUtil;

import java.util.Enumeration;

/**
 * Description: <br>
 *
 * @author bks <br>
 * @since 2021-08-16 <br>
 */
public class LoggerFactory implements JingLoggerFactoryItf {
    private LoggerLevel globalLevel;

    @Override public void init(JingLoggerConfiguration configuration) {
        SingleLogger.log("init Logger.LOG4J...");
    }

    @Override public boolean isEnable() {
        try {
            Class.forName("org.apache.log4j.Logger");
        }
        catch (Throwable t) {
            return false;
        }
        return true;
    }

    @Override
    public JingLoggerItf getLogger(String name) {
        return new Logger(name);
    }

    @Override
    public JingLoggerItf getLogger(Class clazz) {
        return new Logger(clazz);
    }

    @Override public boolean isAllEnable() {
        return LoggerLevel.ALL.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isTraceEnable() {
        return LoggerLevel.TRACE.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isDebugEnable() {
        return LoggerLevel.DEBUG.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isInfoEnable() {
        return LoggerLevel.INFO.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isWarnEnable() {
        return LoggerLevel.WARN.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isImpEnable() {
        return LoggerLevel.IMP.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isSqlEnable() {
        return LoggerLevel.SQL.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isErrorEnable() {
        return LoggerLevel.ERROR.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isFatalEnable() {
        return LoggerLevel.FATAL.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isOffEnable() {
        return LoggerLevel.OFF.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isLevelEnable(JingLoggerLevelItf level) {
        return level.isGreaterOrEquals(globalLevel);
    }

    @Override public void setGlobalLevel(String levelStr) throws JingException {
        if (StringUtil.isEmpty(levelStr)) {
            globalLevel = LoggerLevel.DEFAULT_LEVEL;
        }
        else {
            switch (levelStr.toUpperCase()) {
                case "ALL": globalLevel = LoggerLevel.ALL; break;
                case "TRACE": globalLevel = LoggerLevel.TRACE; break;
                case "DEBUG": globalLevel = LoggerLevel.DEBUG; break;
                case "INFO": globalLevel = LoggerLevel.INFO; break;
                case "WARN": globalLevel = LoggerLevel.WARN; break;
                case "ERROR": globalLevel = LoggerLevel.ERROR; break;
                case "SQL": globalLevel = LoggerLevel.SQL; break;
                case "IMP": globalLevel = LoggerLevel.IMP; break;
                case "FATAL": globalLevel = LoggerLevel.FATAL; break;
                case "OFF": globalLevel = LoggerLevel.OFF; break;
                default: throw new JingException("invalid logger level: {}", levelStr);
            }
            org.apache.log4j.Logger.getRootLogger().setLevel(globalLevel);
            LoggerRepository repository = LogManager.getLoggerRepository();
            Enumeration enumeration = repository.getCurrentCategories();
            while (enumeration.hasMoreElements()) {
                ((org.apache.log4j.Logger) enumeration.nextElement()).setLevel(globalLevel);
            }
        }
    }
}
